"""
@author:王耀
@date:2021/9/21
"""
import cv2
import math
import numpy as np

def allMax(img):
    maxForRow = []
    W, H = img.shape
    for i in range(W):
        maxForRow.append(max(img[i, :]))
    return (max(maxForRow))

def allMin(img):
    minForRow = []
    W, H = img.shape
    for i in range(W):
        minForRow.append(min(img[i, :]))
    return (min(minForRow))

def otsuThred(img):
    """
    作用：Otsu算法获得sigma最大的两个阈值
    img：输入的图像

    :return: 两个阈值
    """
    if img is None:
        raise Exception('input image ERROR!')
    W, H = img.shape
    if W <= 0 or H <= 0:
        raise Exception('input picture ERROR...')

    # 获得一张图片中最大和最小的像素值
    grayMax = allMax(img)
    grayMin = allMin(img)

    grayScaleP = np.zeros(256)  # 统计每个灰度级的像素点个数
    grayScaleStatis = set()  # 便于统计的set
    for i in range(W):
        for j in range(H):
            if int(img[i, j]) in grayScaleStatis:
                grayScaleP[int(img[i, j])] += 1
            else:
                grayScaleStatis.add(int(img[i, j]))
    grayScaleP = grayScaleP / (W * H)  # 获得每个像素的频率

    MG = 0  # 灰度等级均值
    for index in range(len(grayScaleP)):
        MG += (index * grayScaleP[index])

    # 根据公式寻找最大的sigma
    P1 = 0
    M = 0
    sigmamax = 0
    k = 0
    for i in range(len(grayScaleP)):
        M += i * grayScaleP[i]
        P1 += grayScaleP[i]
        sigma = ((MG * P1 - M) ** 2) / (P1 * (1 - P1))  # 根据公式计算sigma^2
        if sigmamax < sigma:
            sigmamax = sigma
            k = i

    # 根据求到的最大的sigma获得高低阈值
    sigmastar = math.sqrt(sigmamax) * (grayMax - grayMin) / 255 + grayMin
    TL = k * (grayMax - grayMin) / 255 + grayMin - sigmastar
    TH = k * (grayMax - grayMin) / 255 + grayMin + sigmastar

    print('执行完毕：Otsu算法')

    return TL, TH